<script lang="ts">
	import { onMount, untrack } from 'svelte';
	import { type TableState } from '../store/table-state.svelte';
	import { type HeaderCell, type ColumnConfig } from '../context/table-context';
	import Icon from '$lib/components/Basic/Icon/Icon.svelte';
	import CheckSquare from '$lib/components/Form/Checkbox/CheckSquare.svelte';
	import PopoverSlot from '$lib/components/Basic/Popover/PopoverSlot.svelte';
	import Portal from 'svelte-portal';
	import { ensurePortalContainer } from '$lib/utils/container/ensurePortalContainer';
	import { getElementRelativePos } from '$lib/utils/position/getElementPos';
	import { cloneDeep, throttle } from 'lodash-es';
	import { getLeafKeys } from '../utils/common';
	import Input from '$lib/components/Form/Input/Input.svelte';
	import Divider from '$lib/components/Basic/Divider/Divider.svelte';
	import Checkbox from '$lib/components/Form/Checkbox/Checkbox.svelte';
	import CheckboxGroup from '$lib/components/Form/Checkbox/CheckboxGroup.svelte';
	import CheckboxSelectAll from '$lib/components/Form/Checkbox/CheckboxSelectAll.svelte';
	import RectButton from '$lib/components/Basic/Button/RectButton.svelte';
	import Badge from '$lib/components/Data/Badge/Badge.svelte';

	interface Props {
		tableState: TableState; // 接收整个状态对象
		size: 'sm' | 'md' | 'lg';
		actRowHeight: number;
		multiple?: boolean;
		theadClass?: string;
		border?: boolean;
		tableContainerRef: HTMLElement | undefined;
		headerScrollContainerRef: HTMLElement | undefined;
		onFilterChange?: (col: string, val: any) => void;
		onSortChange?: (state: any) => void;
	}

	let {
		tableState,
		size,
		actRowHeight,
		multiple,
		theadClass,
		border = false,
		tableContainerRef = $bindable(),
		headerScrollContainerRef = $bindable(),
		onFilterChange,
		onSortChange
	}: Props = $props();

	// ... 移植 resize 拖拽逻辑，直接操作 tableState.columnWidths
	// 新增：临时筛选值（用于筛选下拉框的精确匹配）
	const tempOptionFilters = $state<Record<string, (string | number)[]>>({});
	// 新增：临时关键字筛选值（用于模糊匹配）
	const tempKeywordFilters = $state<Record<string, (string | number)[]>>({});
	// 新增：筛选下拉框显示状态
	// 新增：筛选状态
	let portalContainer: HTMLElement | undefined = $state(undefined);
	let popoverSlotRefs: Record<string, HTMLElement | undefined> = $state({});
	let triggerRefs: Record<string, HTMLElement | undefined> = $state({});
	let triggerRects: Record<
		string,
		{
			top: number;
			left: number;
			bottom: number;
			right: number;
			width: number;
			height: number;
		}
	> = {};
	let filterDropdownVisible = $state<ColumnConfig['key'] | null>(null);
	let filterDropdownColumn: ColumnConfig | null = null;
	let filterKeyword = $state<string>(''); //用于搜索下拉框
	const toggleFilterDropdown = (col: ColumnConfig) => {
		if (!col.filterable) return;
		if (filterDropdownVisible === col.key) {
			filterDropdownVisible = null;
			filterDropdownColumn = null;
			document.removeEventListener('mousedown', handleClickOutside);
			window.removeEventListener('keydown', handleEscape);
		} else {
			filterDropdownVisible = col.key;
			filterDropdownColumn = col;
			triggerRects[col.key as string] = getElementRelativePos(triggerRefs[col.key as string]!);
			// 初始化临时筛选值：确保始终是 value 数组
			filterKeyword = '';
			const currentFilter = tableState.optionFilterState[col.key as string] || [];
			tempOptionFilters[col.key as string] = Array.isArray(currentFilter)
				? [...currentFilter]
				: currentFilter
					? [currentFilter]
					: [];
			const currentKeywordFilter = tableState.keywordFilterState[col.key as string] || [];
			tempKeywordFilters[col.key as string] = Array.isArray(currentKeywordFilter)
				? [...currentKeywordFilter]
				: currentKeywordFilter
					? [currentKeywordFilter]
					: [];
			document.addEventListener('mousedown', handleClickOutside);
			window.addEventListener('keydown', handleEscape);
		}
	};
	const handleSortClick = (e: MouseEvent, config: ColumnConfig) => {
		e.stopPropagation();
		if (!config.sortable) return;
		const isMultiSort = e.ctrlKey || e.metaKey;
		tableState.handleSort(config.key, isMultiSort);
	};
	const handleClickOutside = (event: MouseEvent) => {
		if (!filterDropdownColumn || !filterDropdownColumn.key) return;
		const popoverRef = popoverSlotRefs?.[filterDropdownColumn.key as string];
		const triggerRef = triggerRefs?.[filterDropdownColumn.key as string];
		if (
			popoverRef && // 弹窗容器存在
			triggerRef && // 触发元素存在
			!popoverRef.contains(event.target as Node) && // 点击不在弹窗内
			!triggerRef.contains(event.target as Node) // 点击不在触发元素内
		) {
			toggleFilterDropdown(filterDropdownColumn);
		}
	};

	const handleEscape = (event: KeyboardEvent) => {
		if (!filterDropdownColumn || !filterDropdownColumn.key) return;
		if (event.key === 'Escape') {
			toggleFilterDropdown(filterDropdownColumn);
		}
	};
	/** 确认筛选 */
	const handleFilterConfirm = (
		col: ColumnConfig,
		valueType: 'option' | 'string' | 'customize',
		customValue?: any
	) => {
		if (valueType === 'customize') {
			const currentFilter = cloneDeep(customValue);
			tableState.setFilter(col.key, currentFilter, valueType);
			toggleFilterDropdown(col);
			return;
		}
		let values: (string | number)[] = [];
		if (valueType === 'option') {
			const currentFilter = tempOptionFilters[col.key as string] || [];
			values = Array.isArray(currentFilter) ? [...currentFilter] : [currentFilter];
		} else if (valueType === 'string') {
			const currentFilter = tempKeywordFilters[col.key as string] || [];
			values = Array.isArray(currentFilter) ? [...currentFilter] : [currentFilter];
		}
		// 确保传递有效的筛选值
		if (values.length > 0) {
			tableState.setFilter(col.key, values, valueType);
		} else {
			// 清除筛选时传递undefined
			tableState.setFilter(col.key, undefined, valueType);
		}
		toggleFilterDropdown(col);
	};

	/** 重置筛选 */
	const handleFilterReset = (col: ColumnConfig) => {
		const key = col.key as string;
		// 清除精确匹配的临时筛选值
		delete tempOptionFilters[key];
		// 清除模糊匹配的临时关键字
		delete tempKeywordFilters[key];
		tableState.setFilter(col.key, undefined, 'delete');
		toggleFilterDropdown(col);
	};
	onMount(() => {
		portalContainer = ensurePortalContainer('table-popovers-container');
	});
	// 全选框状态
	let isAllSelected = $derived.by(() => {
		if (tableState.selectionVersion === 0 || tableState.processedData.length === 0) return false;

		if (tableState.isExcludeMode) {
			// 全选模式下：只有当没有排除项(Map为空)时，才是完全的全选状态
			return tableState.selectedKeys.size === 0;
		} else {
			// 默认模式下：选中数量等于数据总长
			return tableState.selectedKeys.size === tableState.processedData.length;
		}
	});

	// 半选状态 (Indeterminate)
	let isIndeterminate = $derived.by(() => {
		if (tableState.selectionVersion === 0 || tableState.processedData.length === 0) return false;
		return (
			tableState.selectedKeys.size > 0 &&
			tableState.selectedKeys.size < tableState.processedData.length
		);
	});

	// --- 🔥 拖拽逻辑重构 ---
	let resizingGroupKeys: string[] = []; // 当前拖拽列涉及的所有叶子 Key
	let startLeafWidths: Record<string, number> = {}; // 拖拽开始时各叶子的宽度
	let startGroupWidth = 0; // 拖拽开始时分组的总宽
	let draggingCol: string | null = null;
	// 新增：指示线相关变量
	let showGuideLine = $state(false); // 指示线是否显示
	let guideLineLeft = $state(0); // 指示线水平位置（相对于表格容器）
	let guideLineHeight = $state(0); // 指示线高度（与表格一致）
	let currentColOffsetLeft = 0; // 当前拖拽列的左侧偏移量（相对于表格容器内容区）
	let tableContainerLeft = 0;
	let currentMinWidth: number = 0; // 默认最小宽（ fallback
	let minDragLeft = 0;
	let maxDragLeft = 0;
	const startDrag = (e: MouseEvent, col: ColumnConfig) => {
		e.preventDefault();
		e.stopPropagation(); // 防止冒泡
		draggingCol = col.key as string;

		const resizeElement = e.currentTarget as HTMLElement;
		const thElement = resizeElement.closest('.table-th') as HTMLElement; // 获取当前 TH
		if (!tableContainerRef || !thElement) return;

		// 获取涉及的所有叶子节点
		resizingGroupKeys = getLeafKeys(col);

		// 记录初始状态
		startLeafWidths = {};
		startGroupWidth = 0;
		resizingGroupKeys.forEach((key) => {
			const w = tableState.getColWidthVal(key);
			startLeafWidths[key] = w;
			startGroupWidth += w;
		});

		// 指示线逻辑
		const tableRect = tableContainerRef.getBoundingClientRect();
		const thRect = thElement.getBoundingClientRect();
		tableContainerLeft = tableRect.left;

		// 指示线位置计算：基于当前被拖拽的 TH 的右边界
		// 注意：如果是分组表头，thRect.right 实际上是最后一列的右边界
		currentColOffsetLeft = thRect.left - tableContainerLeft;
		guideLineLeft = thRect.right - tableContainerLeft;
		guideLineHeight = tableContainerRef.offsetHeight;

		// 最小宽度限制 (简单处理：每列最小 30)
		currentMinWidth = resizingGroupKeys.length * 30;

		showGuideLine = true;
		document.body.style.userSelect = 'none';

		minDragLeft = currentColOffsetLeft + currentMinWidth;
		maxDragLeft = tableContainerRef.clientWidth;

		document.addEventListener('mousemove', handleDrag);
		document.addEventListener('mouseup', stopDrag);
	};

	const handleDrag = throttle((e: MouseEvent) => {
		if (!draggingCol || !tableContainerRef) return;
		// 鼠标X坐标 = 鼠标绝对X - 表格容器左边界 - 容器内边距 + 容器横向滚动量
		const mouseXInContainer = e.clientX - tableContainerLeft;

		guideLineLeft = Math.max(minDragLeft, Math.min(maxDragLeft, mouseXInContainer));
	}, 16);

	const stopDrag = () => {
		if (draggingCol && tableContainerRef) {
			// 计算新总宽
			let newTotalWidth = guideLineLeft - currentColOffsetLeft;
			if (newTotalWidth < currentMinWidth) newTotalWidth = currentMinWidth;

			// 🔥 比例分配逻辑
			// 如果拖的是叶子，resizingGroupKeys 只有一个，ratio = 1 (直接设置)
			// 如果拖的是组，所有子列按比例缩放
			const ratio = newTotalWidth / startGroupWidth;

			const updatedWidths = { ...tableState.columnWidths };

			// 必须保留至少1px以防除以0或负数，虽然 minWidth 已控制
			resizingGroupKeys.forEach((key) => {
				const originalW = startLeafWidths[key];
				const newW = Math.floor(originalW * ratio); // 取整避免像素对齐问题

				// 更新 width 配置（用于下次 resize 计算）
				const col = tableState.columns.find((c) => c.key === key);
				if (col) col.width = newW;

				updatedWidths[key] = newW;
			});

			tableState.columnWidths = updatedWidths;
		}

		showGuideLine = false;
		draggingCol = null;
		resizingGroupKeys = [];
		document.body.style.userSelect = '';
		document.removeEventListener('mousemove', handleDrag);
		document.removeEventListener('mouseup', stopDrag);
	};
	// 新增：筛选选项类型
	interface FilterOption {
		label: string;
		value: any;
	}
	// 新增：筛选选项缓存
	const filterOptionsCache = $state<Record<string, FilterOption[]>>({});
	// 新增：筛选选项加载状态
	const filterOptionsLoading = $state<Record<string, boolean>>({});
	/** 异步生成筛选选项 */
	const generateFilterOptions = async (col: ColumnConfig) => {
		const key = col.key as string;
		if (
			tableState.rawData.length === 0 ||
			tableState.rawData.length > tableState.MAX_FILTER_OPTIONS
		)
			return;
		// 如果已经在加载中，则不重复加载
		if (filterOptionsLoading[key]) return;

		filterOptionsLoading[key] = true;
		try {
			// 使用setTimeout将计算放入下一个事件循环，避免阻塞UI
			await new Promise((resolve) => setTimeout(resolve, 0));

			// 优化的去重算法：使用Map单次遍历完成去重，避免多次遍历
			const valueMap = new Map<any, boolean>();
			const options: FilterOption[] = [];

			// 单次遍历完成去重和过滤
			for (let i = 0; i < tableState.rawData.length; i++) {
				const value = tableState.rawData[i][col.key as string];
				// 过滤掉undefined和null，并使用Map去重
				if (value !== undefined && value !== null && !valueMap.has(value)) {
					valueMap.set(value, true);
					options.push({
						label: String(value),
						value
					});
				}
			}

			// 缓存结果
			filterOptionsCache[key] = options;
		} finally {
			// 无论成功失败，都要更新加载状态
			filterOptionsLoading[key] = false;
		}
	};
	$effect(() => {
		if (tableState.rawData.length > 0) {
			untrack(() => {
				tableState.columns.forEach((col) => {
					if (col.filterable && col.dataFilters) {
						generateFilterOptions(col);
					}
				});
			});
		}
	});
</script>

{#if showGuideLine}
	<div
		class="resize-guide-line"
		style:left={`${guideLineLeft}px`}
		style:height={`${guideLineHeight}px`}
	></div>
{/if}
<div class={`table-thead ${theadClass}`} bind:this={headerScrollContainerRef} class:table--border={border}>
	{#if multiple}
		<div
			class="check-box-container"
			style:height={`${tableState.headerData.maxDepth * actRowHeight}px`}
			style:width="30px"
		>
			<CheckSquare
				{size}
				checked={isAllSelected}
				indeterminate={isIndeterminate}
				onChange={(checked) => tableState.toggleAllSelection(checked)}
			/>
		</div>
	{/if}

	{#snippet headerNode(cell: HeaderCell)}
		<div class="header-column-container" style:width={`${tableState.getGroupWidth(cell.config)}px`}>
			<div
				class="table-th"
				class:is-group={cell.isGroup}
				style:height={`${cell.rowSpan * actRowHeight}px`}
				style:width="100%"
				style:--text-align={cell.config.align}
			>
				<div class="th-content">
					{#if cell.config.slots.header}
						{@render cell.config.slots.header()}
					{:else}
						{cell.config.title}
					{/if}

					<!-- 排序图标 -->
					{#if !cell.isGroup}
						{#if cell.config.sortable}
							{@const currentSort = tableState.sortState.find((s) => s.key === cell.key)}
							{@const sortDir = currentSort?.direction}
							{@const sortIndex =
								tableState.sortState.length > 1
									? tableState.sortState.findIndex((s) => s.key === cell.key) + 1
									: null}
							<div
								class="sort-button"
								onclick={(e) => handleSortClick(e, cell.config)}
								aria-label={sortDir === 'ascend' ? '降序' : sortDir === 'descend' ? '升序' : '排序'}
								role="button"
								tabindex="0"
								onkeydown={() => {}}
							>
								<Icon
									src="symbol/arrow-up-round"
									color={sortDir === 'ascend' ? 'var(--color-primary-600)' : ''}
								/>
								<Icon
									src="symbol/arrow-down-round"
									color={sortDir === 'descend' ? 'var(--color-primary-600)' : ''}
								/>
								{#if sortIndex}
									<span class="sort-index">{sortIndex}</span>
								{/if}
							</div>
						{/if}
					{/if}

					<!-- 筛选图标 -->
					{#if cell.config.filterable}
						<div
							class={`filter-button ${tableState.optionFilterState[cell.key as string] ? 'active' : ''}`}
							onclick={() => toggleFilterDropdown(cell.config)}
							aria-label="筛选"
							role="button"
							tabindex="0"
							onkeydown={() => {}}
							style:margin-top="1px"
							bind:this={triggerRefs[cell.key as string]}
							class:is-active={tableState.optionFilterState[cell.key as string] ||
								tableState.keywordFilterState[cell.key as string] ||
								tableState.customFilterState[cell.key as string]}
						>
							<Icon src="office/filter" />
						</div>
					{/if}
				</div>

				<div
					class="resize-handle"
					onmousedown={(e) => startDrag(e, cell.config)}
					role="button"
					tabindex="0"
				></div>

				<!-- 筛选下拉框 -->
				{#if filterDropdownVisible === cell.key && cell.config.filterable}
					<Portal target={portalContainer}>
						<PopoverSlot
							triggerRect={triggerRects[cell.key as string]}
							placement="bottom"
							translateX={-20}
							bind:popoverRef={popoverSlotRefs[cell.key as string]}
							style="padding: 8px;"
						>
							{#if cell.config.slots.filterDropdown}
								{@render cell.config.slots.filterDropdown({
									column: cell.config,
									// 把当前存储的自定义值传出去，以便父组件回显 (例如输入框的值)
									value: tableState.customFilterState[cell.key as string],

									// 这里的 val 就是父组件调用 onConfirm 时传进来的自定义对象
									onConfirm: (val) => handleFilterConfirm(cell.config, 'customize', val),
									onReset: () => handleFilterReset(cell.config),
									onClose: () => toggleFilterDropdown(cell.config)
								})}
							{:else if cell.config.dataFilters}
								{#if tableState.rawData.length < tableState.MAX_FILTER_OPTIONS + 1}
									{#key cell.key}
										<!-- 使用缓存的筛选选项 -->
										{@const key = cell.key as string}
										{@const options = filterOptionsCache[key] || []}
										<div class="filter-keyword" style:width={size === 'sm' ? '200px' : '240px'}>
											<Input {size} placeholder="搜索选择项" bind:value={filterKeyword} />
										</div>
										<Divider style="dashed" margin="8px" />
										<div class="filter-options">
											<div class="filter-checkbox-select-all">
												<CheckboxSelectAll
													{size}
													label="全选"
													{options}
													bind:modelValue={tempOptionFilters[key]}
												/>
												{#if tempOptionFilters[key].length > 0}
													<Badge value={tempOptionFilters[key].length} variant="primary" {size} />
												{/if}
											</div>
											<div class="filter-checkbox-group-container">
												<CheckboxGroup
													bind:modelValue={tempOptionFilters[key]}
													{size}
													className="filter-checkbox-group"
												>
													{#each options as option}
														<Checkbox
															value={option.value}
															label={option.label}
															className={!option.label
																.toLowerCase()
																.includes(filterKeyword.toLowerCase().trim()) &&
															filterKeyword !== ''
																? 'filter-checkbox-hidden'
																: ''}
														/>
													{/each}
												</CheckboxGroup>
											</div>
										</div>
										<Divider style="dashed" margin="8px" />
									{/key}
								{:else}
									<div class="filter-keyword" style:width={size === 'sm' ? '200px' : '240px'}>
										<Input
											{size}
											placeholder="输入关键字筛选"
											bind:value={tempKeywordFilters[cell.key as string][0]}
											onKeydown={(event) => {
												if (event.key === 'Enter') {
													handleFilterConfirm(cell.config, 'string');
												}
											}}
										/>
									</div>
									<Divider style="dashed" margin="8px" />
								{/if}
								<div class="filter-actions">
									<RectButton
										label="重置"
										variant="info"
										type="link"
										onClick={() => handleFilterReset(cell.config)}
										{size}
										style="height: auto;padding:4px 10px;"
									></RectButton>
									<RectButton
										label="筛选"
										variant="primary"
										type="link"
										onClick={() =>
											handleFilterConfirm(
												cell.config,
												tableState.rawData.length < tableState.MAX_FILTER_OPTIONS + 1
													? 'option'
													: 'string'
											)}
										{size}
										style="height: auto;padding:4px 10px;"
									></RectButton>
								</div>
							{:else if cell.config.filters}
								<div class="filter-options">
									<div class="filter-keyword" style:width={size === 'sm' ? '200px' : '240px'}>
										<Input {size} placeholder="搜索选择项" bind:value={filterKeyword} />
									</div>
									<Divider style="dashed" margin="8px" />
									<div class="filter-checkbox-select-all">
										<CheckboxSelectAll
											{size}
											label="全选"
											options={cell.config.filters}
											bind:modelValue={tempOptionFilters[cell.key as string]}
										/>
										{#if tempOptionFilters[cell.key as string].length > 0}
											<Badge
												value={tempOptionFilters[cell.key as string].length}
												variant="primary"
												{size}
											/>
										{/if}
									</div>
									<div class="filter-checkbox-group-container">
										<CheckboxGroup
											bind:modelValue={tempOptionFilters[cell.key as string]}
											{size}
											className="filter-checkbox-group"
										>
											{#each cell.config.filters as option}
												<Checkbox
													value={option.value}
													label={option.label}
													className={!option.label
														.toLowerCase()
														.includes(filterKeyword.toLowerCase().trim()) && filterKeyword !== ''
														? 'filter-checkbox-hidden'
														: ''}
												/>
											{/each}
										</CheckboxGroup>
									</div>
								</div>
								<Divider style="dashed" margin="8px" />
								<div class="filter-actions">
									<RectButton
										label="重置"
										variant="info"
										type="link"
										onClick={() => handleFilterReset(cell.config)}
										{size}
										style="height: auto;padding:4px 10px;"
									></RectButton>
									<RectButton
										label="筛选"
										variant="primary"
										type="link"
										onClick={() => handleFilterConfirm(cell.config, 'option')}
										{size}
										style="height: auto;padding:4px 10px;"
									></RectButton>
								</div>
							{:else}
								<div class="filter-keyword" style:width={size === 'sm' ? '200px' : '240px'}>
									<Input
										{size}
										placeholder="输入关键字筛选"
										bind:value={tempKeywordFilters[cell.key as string][0]}
										onKeydown={(event) => {
											if (event.key === 'Enter') {
												handleFilterConfirm(cell.config, 'string');
											}
										}}
									/>
								</div>
								<Divider style="dashed" margin="8px" />
								<div class="filter-actions">
									<RectButton
										label="重置"
										variant="info"
										type="link"
										onClick={() => handleFilterReset(cell.config)}
										{size}
										style="height: auto;padding:4px 10px;"
									></RectButton>
									<RectButton
										label="筛选"
										variant="primary"
										type="link"
										onClick={() => handleFilterConfirm(cell.config, 'string')}
										{size}
										style="height: auto;padding:4px 10px;"
									></RectButton>
								</div>
							{/if}
						</PopoverSlot>
					</Portal>
				{/if}
			</div>
			<!-- B. 子节点容器 (递归入口) -->
			{#if cell.children && cell.children.length > 0}
				<div class="header-children-row">
					{#each cell.children as child (child.key)}
						{@render headerNode(child)}
					{/each}
				</div>
			{/if}
		</div>
	{/snippet}

	{#each tableState.headerData.cols as cell (cell.key)}
		{@render headerNode(cell)}
	{/each}
</div>

<style lang="scss">
	@use '../styles/tableHeader.scss';
</style>
